/**
 * 作者：邓伟
 * 网站：https://mqtt.vb6.pro
 */
const { createApp } = Vue

createApp({
    data() {
        return {
            client: null,
            connected: false,
            messages: [],
            newMessage: '',
            portsExpanded: false, // 控制端口信息面板的展开状态
            serverInfo: {
                broker: 'broker.emqx.io',
                tcp: '1883',
                ws: '8083',
                ssl: '8883',
                wss: '8084',
                quic: '14567'
            },
            topic: 'vbman/test',
            clientId: 'vbman_' + Math.random().toString(16).substr(2, 8),
            darkMode: localStorage.getItem('darkMode') === 'true',
            soundEnabled: localStorage.getItem('soundEnabled') !== 'false', // 默认开启声音
            toast: {
                show: false,
                message: '',
                type: 'info',
                timer: null
            },
            subscriberCount: 0,  // 订阅人数计数
            sidebarVisible: window.innerWidth > 768, // 默认在桌面端显示，移动端隐藏
        }
    },
    computed: {
        countTopic() {
            return `${this.topic}/count`;
        },
        actionTopic() {
            return `${this.topic}/action`;
        }
    },
    methods: {
        showToast(message, type = 'info', duration = 3000) {
            // 清除之前的定时器
            if (this.toast.timer) {
                clearTimeout(this.toast.timer);
            }

            // 显示新的toast
            this.toast.show = true;
            this.toast.message = message;
            this.toast.type = type;

            // 设置定时器自动关闭
            this.toast.timer = setTimeout(() => {
                this.toast.show = false;
            }, duration);
        },
        toggleConnection() {
            if (this.connected) {
                this.disconnectMqtt();
            } else {
                this.showToast('正在连接...', 'info');
                this.initMqttClient();
            }
        },
        disconnectMqtt() {
            if (this.client) {
                this.showToast('正在断开连接...', 'warning');
                // 发送离开消息
                const leaveMessage = {
                    type: 'leave',
                    senderId: this.clientId,
                    timestamp: new Date().getTime()
                };

                // 更新并发布新的订阅人数
                if (this.subscriberCount > 0) {
                    const newCount = this.subscriberCount - 1;
                    this.client.publish(this.countTopic, newCount.toString(), { retain: true }, () => {
                        // 发布离开消息
                        this.client.publish(this.actionTopic, JSON.stringify(leaveMessage), () => {
                            this.client.end(true, () => {
                                console.log('Disconnected from broker');
                                this.connected = false;
                                this.messages = []; // 清空消息列表
                                this.subscriberCount = 0; // 重置订阅数
                                this.showToast('已断开连接', 'info');
                            });
                        });
                    });
                } else {
                    this.client.end(true, () => {
                        console.log('Disconnected from broker');
                        this.connected = false;
                        this.messages = []; // 清空消息列表
                        this.subscriberCount = 0; // 重置订阅数
                        this.showToast('已断开连接', 'info');
                    });
                }
            }
        },
        initMqttClient() {
            if (this.client) {
                this.client.end(true);
            }
            this.showToast('正在初始化连接...', 'info');
            // 确保客户端ID唯一
            const options = {
                clientId: this.clientId,
                clean: true,
                connectTimeout: 4000,
                reconnectPeriod: 4000,
            }

            const connectUrl = `wss://${this.serverInfo.broker}:${this.serverInfo.wss}/mqtt`
            this.client = mqtt.connect(connectUrl, options)

            this.client.on('connect', () => {
                console.log('Connection succeeded!')
                this.connected = true
                this.showToast('连接成功', 'success');

                // 订阅常规主题和系统主题
                this.client.subscribe([this.topic, this.countTopic, this.actionTopic], (err) => {
                    if (!err) {
                        console.log('Successfully subscribed to', this.topic)
                        this.showToast(`已订阅主题: ${this.topic}`, 'success');
                        // 发布加入消息
                        const joinMessage = {
                            type: 'join',
                            senderId: this.clientId,
                            timestamp: new Date().getTime()
                        };
                        this.messages.push({
                            senderId: '系统',
                            timestamp: new Date().getTime(),
                            content: `已成功订阅主题: ${this.topic}`,
                            type: 'received'
                        });
                        // 发布加入消息到系统主题
                        this.client.publish(this.actionTopic, JSON.stringify(joinMessage));

                        // 延迟1秒检查是否收到了保留的订阅人数
                        setTimeout(() => {
                            if (this.subscriberCount === 0) {
                                // 如果1秒后还没收到计数，说明是第一个客户端
                                this.subscriberCount = 1;
                                this.client.publish(this.countTopic, '1', { retain: true });
                            } else {
                                // 已经收到了保留的计数，增加并更新
                                this.subscriberCount++;
                                this.client.publish(this.countTopic, this.subscriberCount.toString(), { retain: true });
                            }
                        }, 1000);
                    } else {
                        this.showToast('订阅失败', 'error');
                    }
                });

                // 在断开连接前发送离开消息和更新订阅数
                window.addEventListener('beforeunload', (event) => {
                    if (this.client && this.connected) {
                        // 更新订阅人数
                        const newCount = this.subscriberCount > 0 ? this.subscriberCount - 1 : 0;

                        // 发送新的订阅数（设置retain为true）
                        this.client.publish(this.countTopic, newCount.toString(), { retain: true });

                        // 发送离开消息
                        const leaveMessage = {
                            type: 'leave',
                            senderId: this.clientId,
                            timestamp: new Date().getTime()
                        };
                        this.client.publish(this.actionTopic, JSON.stringify(leaveMessage));

                        // 确保消息发送完成
                        event.preventDefault();
                        event.returnValue = '';
                    }
                });
            });

            this.client.on('message', (topic, payload) => {
                const msgStr = payload.toString();

                if (topic === this.countTopic) {
                    // 处理系统消息（订阅人数）
                    const count = parseInt(msgStr);
                    if (!isNaN(count)) {
                        this.subscriberCount = count;
                    }
                } else if (topic === this.actionTopic) {
                    // 处理加入/离开消息
                    try {
                        let messageObj = JSON.parse(msgStr);
                        if (messageObj.senderId !== this.clientId) {
                            if (messageObj.type === 'join') {
                                this.showToast(`${messageObj.senderId} 进入频道`, 'info');
                                this.playSound('join');
                            } else if (messageObj.type === 'leave') {
                                this.showToast(`${messageObj.senderId} 离开频道`, 'warning');
                                this.playSound('leave');
                            }
                        }
                    } catch (e) {
                        console.error('Error parsing join/leave message:', e);
                    }
                } else {
                    // 处理普通消息
                    try {
                        let messageObj = JSON.parse(msgStr);

                        // 如果是自己的消息就忽略
                        if (messageObj.senderId === this.clientId) return;

                        this.messages.push({
                            content: messageObj.content,
                            type: 'received',
                            senderId: messageObj.senderId,
                            timestamp: messageObj.timestamp
                        });

                        this.playSound('receive');

                        this.$nextTick(() => {
                            this.scrollToBottom();
                        });
                    } catch (error) {
                        // console.error('Error processing message:', error);
                        // 如果消息解析失败，可能是非JSON格式的消息，直接显示
                        this.messages.push({
                            content: msgStr,
                            type: 'received',
                            senderId: '未知客户端',
                            timestamp: new Date().getTime()
                        });
                        this.playSound('receive');
                        this.$nextTick(() => {
                            this.scrollToBottom();
                        });
                    }
                }
            });

            this.client.on('error', (error) => {
                console.log('Connection failed', error)
                this.connected = false
                this.showToast('连接失败', 'error');
            })

            this.client.on('close', () => {
                console.log('Connection closed')
                this.connected = false
                if (this.client && this.client.disconnecting) {
                    // 正常断开连接，不显示toast（已经在disconnectMqtt中显示了）
                    return;
                }
                this.showToast('连接已断开', 'error');
                this.messages.push({
                    content: '连接已断开',
                    type: 'received'
                });
            })
        },
        sendMessage() {
            if (!this.newMessage.trim() || !this.connected) return;

            const messageObj = {
                content: this.newMessage,
                senderId: this.clientId,
                timestamp: new Date().getTime()
            };

            this.client.publish(this.topic, JSON.stringify(messageObj));
            this.messages.push({
                content: this.newMessage,
                type: 'sent',
                senderId: this.clientId,
                timestamp: messageObj.timestamp
            });

            // 播放发送音效
            this.playSound('send');

            this.newMessage = '';
            this.$nextTick(() => {
                this.scrollToBottom();
            });
        },
        scrollToBottom() {
            const container = this.$refs.messagesContainer
            container.scrollTop = container.scrollHeight
        },
        async copyText(text) {
            try {
                await navigator.clipboard.writeText(text)
                this.showToast(`已复制文本: ${text}`, 'success');
            } catch (err) {
                console.error('复制失败:', err)
            }
        },
        formatTime(timestamp) {
            const date = new Date(timestamp);
            const hours = date.getHours().toString().padStart(2, '0');
            const minutes = date.getMinutes().toString().padStart(2, '0');
            const seconds = date.getSeconds().toString().padStart(2, '0');
            return `${hours}:${minutes}:${seconds}`;
        },
        toggleTheme() {
            this.darkMode = !this.darkMode;
            localStorage.setItem('darkMode', this.darkMode);
            document.documentElement.setAttribute('data-theme', this.darkMode ? 'dark' : 'light');
            this.showToast(`已切换到${this.darkMode ? '暗色' : '亮色'}主题`, 'info');
        }, playSound(type) {
            if (this.soundEnabled) {
                const soundMap = {
                    'send': 'soundSend',
                    'receive': 'soundReceive',
                    'join': 'soundJoin',
                    'leave': 'soundLeave'
                };
                const audioId = soundMap[type];
                if (audioId) {
                    const audio = document.getElementById(audioId);
                    if (audio) {
                        audio.currentTime = 0;
                        audio.play().catch(e => console.log('Audio play failed:', e));
                    }
                }
            }
        },
        toggleSound() {
            this.soundEnabled = !this.soundEnabled;
            localStorage.setItem('soundEnabled', this.soundEnabled);
            this.showToast(`提示音已${this.soundEnabled ? '开启' : '关闭'}`, 'info');            // 如果开启声音，播放发送音效作为示例
            if (this.soundEnabled) {
                this.playSound('send');
            }
        },
        toggleSidebar() {
            this.sidebarVisible = !this.sidebarVisible;
        },
        handleResize() {
            if (window.innerWidth > 768) {
                this.sidebarVisible = true;
            }
        },
        setSubscriberCount(count) {
            if (!this.client || !this.connected) {
                console.error('MQTT客户端未连接，无法设置订阅数');
                return;
            }
            // 确保count是一个有效的数字
            count = parseInt(count);
            if (isNaN(count) || count < 0) {
                console.error('订阅数必须是一个非负整数');
                return;
            }
            // 更新订阅数并发布
            this.subscriberCount = count;
            this.client.publish(this.countTopic, count.toString(), { retain: true }, () => {
                console.log(`订阅数已更新为: ${count}`);
                this.showToast(`订阅数已手动更新为: ${count}`, 'success');
            });
        },
    },
    mounted() {
        // 初始化主题
        document.documentElement.setAttribute('data-theme', this.darkMode ? 'dark' : 'light');
        this.initMqttClient();

        window.resetSubscriberCount = this.setSubscriberCount;

        // 监听窗口大小变化
        window.addEventListener('resize', this.handleResize);
    },
    beforeDestroy() {
        // 移除事件监听器
        window.removeEventListener('resize', this.handleResize);
    },
}).mount('#app')
